package com.yy.wga.user.service.listener;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yy.wga.module.user.events.UserGradeUpEvent;
import com.yy.wga.user.service.pojo.UserBaseDO;
import com.yy.wga.user.service.pojo.UserGradeRecordDO;
import com.yy.wga.user.service.pojo.UserRelationDO;
import com.yy.wga.module.user.enums.EUserGrade;
import com.yy.wga.module.user.manager.UserManager;
import com.yy.wga.module.user.service.UserBaseService;
import com.yy.wga.module.user.service.UserGradeRecordService;
import com.yy.wga.module.user.service.UserRelationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: gc
 * @Date: 2024/11/27
 * @Description:
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class UserGradeUpListener implements ApplicationListener<UserGradeUpEvent> {

    private final UserBaseService userBaseService;
    private final UserRelationService userRelationService;
    private final UserGradeRecordService userGradeRecordService;
    private final UserManager userManager;


    @Async
    @Transactional
    public void onApplicationEvent(UserGradeUpEvent event) {
        UserBaseDO userBaseDO = userBaseService.getOne(new LambdaQueryWrapper<UserBaseDO>()
                .eq(UserBaseDO::getAppKey, event.getAppKey())
                .eq(UserBaseDO::getId, event.getParentUserId()));
        if (userBaseDO == null) {
            log.error("用户不存在");
            return;
        }

        // V5享客升级事件
        if (event.getUpGrade().equals(EUserGrade.SHARE_5.getType())
                && event.getUpLevel().equals(EUserGrade.SHARE_5.getLevel())) {
            // 如果升级事件是v5享客，但是用户不是v5，不处理
            if (userBaseDO.getGrade().equals(EUserGrade.SHARE_5.getType())
                    && !userBaseDO.getLevel().equals(EUserGrade.SHARE_5.getLevel())) {
                return;
            }
            // 如果是V5享客升级事件，但是用户已经是服务商了，不进行处理
            if (userBaseDO.getGrade().equals(EUserGrade.SERVER_1.getType())) {
                return;
            }

            // 10个V5享客可以升级到服务商V1
            // 上级用户的v5升级时间
            UserGradeRecordDO userGradeRecord = userGradeRecordService.getOne(new LambdaQueryWrapper<UserGradeRecordDO>()
                    .eq(UserGradeRecordDO::getUserId, event.getParentUserId())
                    .eq(UserGradeRecordDO::getGrade, EUserGrade.SHARE_5.getType())
                    .eq(UserGradeRecordDO::getLevel, EUserGrade.SHARE_5.getLevel()));
            if (userGradeRecord == null) {
                log.error("上次大于等于v5享客，但是没有升级记录:{}", event.getParentUserId());
                return;
            }
            // 下级满足v5的用户
            List<UserRelationDO> userRelationList = userRelationService.list(new LambdaQueryWrapper<UserRelationDO>()
                    .eq(UserRelationDO::getAppKey, event.getAppKey())
                    .eq(UserRelationDO::getParentUserId, event.getParentUserId()));
            List<Long> childUserIdList = userRelationList.stream()
                    // 服务商
                    .filter(r -> r.getGrade().equals(EUserGrade.SERVER_1.getType())
                            // v5享客
                            || (r.getGrade().equals(EUserGrade.SHARE_5.getType()) && r.getLevel().equals(EUserGrade.SHARE_5.getLevel())))
                    .map(UserRelationDO::getUserId)
                    .collect(Collectors.toList());
            // 必须要是上级用户升级后产生的用户v5升级才算
            long count = userGradeRecordService.count(new LambdaQueryWrapper<UserGradeRecordDO>()
                    .in(UserGradeRecordDO::getUserId, childUserIdList)
                    .eq(UserGradeRecordDO::getGrade, EUserGrade.SHARE_5.getType())
                    .eq(UserGradeRecordDO::getLevel, EUserGrade.SHARE_5.getLevel())
                    .ge(UserGradeRecordDO::getCreateTime, userGradeRecord.getCreateTime()));
            if (count >= 10) {
                userManager.upgrade(userBaseDO, EUserGrade.SERVER_1);
            }
            return;
        }

        // V2服务商升级事件
        if (event.getUpGrade().equals(EUserGrade.SERVER_2.getType())
                && event.getUpLevel().equals(EUserGrade.SERVER_2.getLevel())) {
            // 如果用户不是服务商，不处理
            if (!userBaseDO.getGrade().equals(EUserGrade.SERVER_1.getType())) {
                return;
            }
            // 用户已经是V2服务商了，不进行处理
            if (userBaseDO.getGrade().equals(EUserGrade.SERVER_2.getType())
                    && userBaseDO.getLevel().equals(EUserGrade.SERVER_2.getLevel())) {
                return;
            }

            // 5个服务商可以升级到服务商V2
            // 上级用户的V1服务商升级时间
            UserGradeRecordDO userGradeRecord = userGradeRecordService.getOne(new LambdaQueryWrapper<UserGradeRecordDO>()
                    .eq(UserGradeRecordDO::getUserId, event.getParentUserId())
                    .eq(UserGradeRecordDO::getGrade, EUserGrade.SERVER_1.getType())
                    .eq(UserGradeRecordDO::getLevel, EUserGrade.SERVER_1.getLevel()));
            if (userGradeRecord == null) {
                log.error("上次大于等于v1服务商，但是没有升级记录:{}", event.getParentUserId());
                return;
            }
            // 下级满足v1服务商的的用户
            List<UserRelationDO> userRelationList = userRelationService.list(new LambdaQueryWrapper<UserRelationDO>()
                    .eq(UserRelationDO::getAppKey, event.getAppKey())
                    .eq(UserRelationDO::getParentUserId, event.getParentUserId())
                    .eq(UserRelationDO::getGrade, EUserGrade.SERVER_1.getType()));
            List<Long> childUserIdList = userRelationList.stream()
                    .map(UserRelationDO::getUserId)
                    .collect(Collectors.toList());
            // 必须要是上级用户升级后产生的用户v5升级才算
            long count = userGradeRecordService.count(new LambdaQueryWrapper<UserGradeRecordDO>()
                    .in(UserGradeRecordDO::getUserId, childUserIdList)
                    .eq(UserGradeRecordDO::getGrade, EUserGrade.SERVER_1.getType())
                    .eq(UserGradeRecordDO::getLevel, EUserGrade.SERVER_1.getLevel())
                    .ge(UserGradeRecordDO::getCreateTime, userGradeRecord.getCreateTime()));
            if (count >= 5) {
                userManager.upgrade(userBaseDO, EUserGrade.SERVER_2);
            }
        }
    }
}
